<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
 <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.21">
 <TITLE>Linux netfilter Hacking HOWTO: Netfilter Architecture</TITLE>
 <LINK HREF="netfilter-hacking-HOWTO-4.html" REL=next>
 <LINK HREF="netfilter-hacking-HOWTO-2.html" REL=previous>
 <LINK HREF="netfilter-hacking-HOWTO.html#toc3" REL=contents>
</HEAD>
<BODY>
<A HREF="netfilter-hacking-HOWTO-4.html">Next</A>
<A HREF="netfilter-hacking-HOWTO-2.html">Previous</A>
<A HREF="netfilter-hacking-HOWTO.html#toc3">Contents</A>
<HR>
<H2><A NAME="s3">3.</A> <A HREF="netfilter-hacking-HOWTO.html#toc3">Netfilter Architecture</A></H2>

<P>Netfilter is merely a series of hooks in various points in a
protocol stack (at this stage, IPv4, IPv6 and DECnet).  The
(idealized) IPv4 traversal diagram looks like the following:</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
A Packet Traversing the Netfilter System:

   --->[1]--->[ROUTE]--->[3]--->[4]--->
                 |            ^
                 |            |
                 |         [ROUTE]
                 v            |
                [2]          [5]
                 |            ^
                 |            |
                 v            |
</PRE>
</CODE></BLOCKQUOTE>
<A NAME="netfilter-traversal"></A> </P>
<P>On the left is where packets come in: having passed the simple sanity
checks (i.e., not truncated, IP checksum OK, not a promiscuous receive),
they are passed to the netfilter framework's NF_IP_PRE_ROUTING [1] hook.</P>

<P>Next they enter the routing code, which decides whether the packet is
destined for another interface, or a local process.  The routing code
may drop packets that are unroutable.</P>

<P>If it's destined for the box itself, the netfilter framework is called
again for the NF_IP_LOCAL_IN [2] hook, before being passed to the
process (if any).</P>

<P>If it's destined to pass to another interface instead, the netfilter
framework is called for the NF_IP_FORWARD [3] hook.</P>

<P>The packet then passes a final netfilter hook, the NF_IP_POST_ROUTING
[4] hook, before being put on the wire again.</P>

<P>The NF_IP_LOCAL_OUT [5] hook is called for packets that are created
locally.  Here you can see that routing occurs after this hook is
called: in fact, the routing code is called first (to figure out the
source IP address and some IP options): if you want to alter the
routing, you must alter the `skb->dst' field yourself, as is done in
the NAT code.</P>

<H2><A NAME="ss3.1">3.1</A> <A HREF="netfilter-hacking-HOWTO.html#toc3.1">Netfilter Base</A>
</H2>

<P>Now we have an example of netfilter for IPv4, you can see when each
hook is activated.  This is the essence of netfilter.</P>

<P>Kernel modules can register to listen at any of these hooks. A module
that registers a function must specify the priority of the function
within the hook; then when that netfilter hook is called from the core
networking code, each module registered at that point is called in the
order of priorites, and is free to manipulate the packet.  The
module can then tell netfilter to do one of five things:</P>
<P>
<OL>
<LI> NF_ACCEPT: continue traversal as normal.</LI>
<LI> NF_DROP: drop the packet; don't continue traversal.</LI>
<LI> NF_STOLEN: I've taken over the packet; don't continue traversal.</LI>
<LI> NF_QUEUE: queue the packet (usually for userspace handling).</LI>
<LI> NF_REPEAT: call this hook again.</LI>
</OL>
</P>

<P>The other parts of netfilter (handling queued packets, cool comments)
will be covered in the kernel section later.</P>

<P>Upon this foundation, we can build fairly complex packet
manipulations, as shown in the next two sections.</P>

<H2><A NAME="ss3.2">3.2</A> <A HREF="netfilter-hacking-HOWTO.html#toc3.2">Packet Selection: IP Tables</A>
</H2>

<P>A packet selection system called IP Tables has been built over the
netfilter framework.  It is a direct descendent of ipchains (that came
from ipfwadm, that came from BSD's ipfw IIRC), with extensibility.
Kernel modules can register a new table, and ask for a packet to
traverse a given table.  This packet selection method is used for
packet filtering (the `filter' table), Network Address Translation
(the `nat' table) and general pre-route packet mangling (the `mangle'
table).</P>

<P>The hooks that are registered with netfilter are as follows (with
the functions in each hook in the order that they are actually
called):</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>

   --->PRE------>[ROUTE]--->FWD---------->POST------>
       Conntrack    |       Mangle   ^    Mangle
       Mangle       |       Filter   |    NAT (Src)
       NAT (Dst)    |                |    Conntrack
       (QDisc)      |             [ROUTE]
                    v                |
                    IN Filter       OUT Conntrack
                    |  Conntrack     ^  Mangle
                    |  Mangle        |  NAT (Dst)
                    v                |  Filter
</PRE>
</CODE></BLOCKQUOTE>
</P>

<H3>Packet Filtering</H3>

<P>This table, `filter', should never alter packets: only filter them.</P>

<P>One of the advantages of iptables filter over ipchains is that it is
small and fast, and it hooks into netfilter at the NF_IP_LOCAL_IN,
NF_IP_FORWARD and NF_IP_LOCAL_OUT points.  This means that for any
given packet, there is one (and only one) possible place to filter it.
This makes things much simpler for users than ipchains was.  Also, the
fact that the netfilter framework provides both the input and output
interfaces for the NF_IP_FORWARD hook means that many kinds of
filtering are far simpler.</P>

<P>Note: I have ported the kernel portions of both ipchains and ipfwadm
as modules on top of netfilter, enabling the use of the old ipfwadm
and ipchains userspace tools without requiring an upgrade.</P>

<H3>NAT</H3>

<P>This is the realm of the `nat' table, which is fed packets from two
netfilter hooks: for non-local packets, the NF_IP_PRE_ROUTING and
NF_IP_POST_ROUTING hooks are perfect for destination and source
alterations respectively.  If CONFIG_IP_NF_NAT_LOCAL is defined, the
hooks NF_IP_LOCAL_OUT and NF_IP_LOCAL_IN are used for altering the
destination of local packets.</P>

<P>This table is slightly different from the `filter' table, in that only
the first packet of a new connection will traverse the table: the
result of this traversal is then applied to all future packets in the
same connection.</P>

<H3>Masquerading, Port Forwarding, Transparent Proxying</H3>

<P>I divide NAT into Source NAT (where the first packet has its source
altered), and Destination NAT (the first packet has its destination
altered).</P>

<P>Masquerading is a special form of Source NAT: port forwarding and
transparent proxying are special forms of Destination NAT.  These are
now all done using the NAT framework, rather than being independent
entities.</P>

<H3>Packet Mangling</H3>

<P>The packet mangling table (the `mangle' table) is used for actual
changing of packet information.  Example applications are the TOS and 
TCPMSS targets.  The mangle table hooks into all five netfilter hooks.
(please note this changed with kernel 2.4.18. Previous kernels didn't
have mangle attached to all hooks)</P>

<H2><A NAME="ss3.3">3.3</A> <A HREF="netfilter-hacking-HOWTO.html#toc3.3">Connection Tracking</A>
</H2>

<P>Connection tracking is fundamental to NAT, but it is implemented as a
separate module; this allows an extension to the packet filtering code
to simply and cleanly use connection tracking (the `state' module).</P>

<H2><A NAME="ss3.4">3.4</A> <A HREF="netfilter-hacking-HOWTO.html#toc3.4">Other Additions</A>
</H2>

<P>The new flexibility provides both the opportunity to do really
funky things, but for people to write enhancements or complete
replacements that can be mixed and matched.</P>

<HR>
<A HREF="netfilter-hacking-HOWTO-4.html">Next</A>
<A HREF="netfilter-hacking-HOWTO-2.html">Previous</A>
<A HREF="netfilter-hacking-HOWTO.html#toc3">Contents</A>
</BODY>
</HTML>
